import { useCallback, useState } from 'react';
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';

interface UseSmartPdfExportOptions {
  filename?: string;
  quality?: number;
  scale?: number;
  useCORS?: boolean;
  allowTaint?: boolean;
  avoidBreakSelectors?: string[]; // 需要避免被切断的元素选择器
}

interface UseSmartPdfExportReturn {
  exportToPdf: (selector?: string) => Promise<void>;
  isExporting: boolean;
  error: string | null;
}

export const useSmartPdfExport = (options: UseSmartPdfExportOptions = {}): UseSmartPdfExportReturn => {
  const [isExporting, setIsExporting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const {
    filename = 'resume.pdf',
    quality = 1,
    scale = 2,
    useCORS = true,
    allowTaint = true,
    avoidBreakSelectors = ['.work', '.skill', '.personal'], // 默认避免切断的元素
  } = options;

  // 获取元素在页面中的位置信息
  const getElementPositions = (containerElement: HTMLElement) => {
    const positions: Array<{ element: HTMLElement; top: number; bottom: number; height: number }> = [];

    avoidBreakSelectors.forEach(selector => {
      const elements = containerElement.querySelectorAll(selector) as NodeListOf<HTMLElement>;
      elements.forEach(element => {
        const rect = element.getBoundingClientRect();
        const containerRect = containerElement.getBoundingClientRect();
        const relativeTop = rect.top - containerRect.top;
        const relativeBottom = relativeTop + rect.height;

        positions.push({
          element,
          top: relativeTop,
          bottom: relativeBottom,
          height: rect.height,
        });
      });
    });

    return positions.sort((a, b) => a.top - b.top);
  };

  // 计算智能分页点
  const calculateBreakPoints = (
    totalHeight: number,
    pageHeight: number,
    elementPositions: Array<{ top: number; bottom: number; height: number }>
  ) => {
    const breakPoints: number[] = [];
    let currentPageBottom = pageHeight;

    while (currentPageBottom < totalHeight) {
      let bestBreakPoint = currentPageBottom;

      // 查找在当前分页点附近的元素
      for (const pos of elementPositions) {
        // 如果元素跨越了分页点
        if (pos.top < currentPageBottom && pos.bottom > currentPageBottom) {
          // 检查是否可以将整个元素放在当前页
          if (pos.top >= currentPageBottom - pageHeight) {
            bestBreakPoint = pos.top;
          } else {
            // 否则将元素放在下一页
            bestBreakPoint = pos.bottom;
          }
          break;
        }
      }

      breakPoints.push(bestBreakPoint);
      currentPageBottom = bestBreakPoint + pageHeight;
    }

    return breakPoints;
  };
  const exportToPdf = useCallback(
    async (selector: string = '.resume-container') => {
      try {
        setIsExporting(true);
        setError(null);

        // 查找目标元素
        const element = document.querySelector(selector) as HTMLElement;
        if (!element) {
          throw new Error(`找不到选择器 "${selector}" 对应的元素`);
        }

        // 获取元素位置信息
        const elementPositions = getElementPositions(element);

        // 使用 html2canvas 将元素转换为 canvas
        const canvas = await html2canvas(element, {
          scale,
          useCORS,
          allowTaint,
          backgroundColor: '#ffffff',
          logging: false,
          width: element.scrollWidth,
          height: element.scrollHeight,
        });

        // 获取 canvas 的尺寸
        const imgWidth = canvas.width;
        const imgHeight = canvas.height;

        // 创建 PDF 文档
        const pdfWidth = 210; // A4 宽度
        const pdfHeight = (imgHeight * pdfWidth) / imgWidth;
        const pageHeight = 297; // A4 页面高度

        const pdf = new jsPDF({
          orientation: 'portrait',
          unit: 'mm',
          format: 'a4',
        });

        if (pdfHeight <= pageHeight) {
          // 内容不超过一页，直接添加
          const imgData = canvas.toDataURL('image/png', quality);
          pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight, undefined, 'FAST');
        } else {
          // 计算智能分页点
          const pixelsPerMM = imgHeight / pdfHeight;
          const pageHeightInPixels = pageHeight * pixelsPerMM;

          // 将元素位置转换为像素坐标
          const elementPositionsInPixels = elementPositions.map(pos => ({
            top: (pos.top / element.scrollHeight) * imgHeight,
            bottom: (pos.bottom / element.scrollHeight) * imgHeight,
            height: (pos.height / element.scrollHeight) * imgHeight,
          }));

          const breakPoints = calculateBreakPoints(imgHeight, pageHeightInPixels, elementPositionsInPixels);

          let currentY = 0;

          // 添加第一页
          const firstPageHeight =
            breakPoints.length > 0
              ? Math.min(breakPoints[0], pageHeightInPixels)
              : Math.min(pageHeightInPixels, imgHeight);

          let pageCanvas = document.createElement('canvas');
          let pageCtx = pageCanvas.getContext('2d')!;
          pageCanvas.width = canvas.width;
          pageCanvas.height = firstPageHeight;

          pageCtx.drawImage(canvas, 0, 0, canvas.width, firstPageHeight, 0, 0, canvas.width, firstPageHeight);

          let pageImgData = pageCanvas.toDataURL('image/png', quality);
          pdf.addImage(pageImgData, 'PNG', 0, 0, pdfWidth, firstPageHeight / pixelsPerMM, undefined, 'FAST');

          currentY = firstPageHeight;

          // 添加后续页面
          for (let i = 0; i < breakPoints.length && currentY < imgHeight; i++) {
            pdf.addPage();

            const nextBreakPoint = i < breakPoints.length - 1 ? breakPoints[i + 1] : imgHeight;
            const currentPageHeight = Math.min(nextBreakPoint - currentY, pageHeightInPixels);

            pageCanvas = document.createElement('canvas');
            pageCtx = pageCanvas.getContext('2d')!;
            pageCanvas.width = canvas.width;
            pageCanvas.height = currentPageHeight;

            pageCtx.drawImage(
              canvas,
              0,
              currentY,
              canvas.width,
              currentPageHeight,
              0,
              0,
              canvas.width,
              currentPageHeight
            );

            pageImgData = pageCanvas.toDataURL('image/png', quality);
            pdf.addImage(pageImgData, 'PNG', 0, 0, pdfWidth, currentPageHeight / pixelsPerMM, undefined, 'FAST');

            currentY += currentPageHeight;
          }
        }

        // 保存 PDF
        pdf.save(filename);
      } catch (err) {
        const errorMessage = err instanceof Error ? err.message : '导出PDF时发生未知错误';
        setError(errorMessage);
        console.error('PDF导出失败:', err);
      } finally {
        setIsExporting(false);
      }
    },
    [filename, quality, scale, useCORS, allowTaint, avoidBreakSelectors]
  );

  return {
    exportToPdf,
    isExporting,
    error,
  };
};
